﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Threading;
using SCB.Bll;
using SCB.Common;

namespace SCB.Presentation.Models
{
    public class DataRespository
    {
        public static ProductsBll ProductService { private set; get; }

        public static void Initialize()
        {
            var ReloadDataTime = DateTime.Parse(ConfigurationManager.AppSettings["ReloadDataTime"]);
            if (ProductService == null)
            {
                ProductService = new ProductsBll(ConfigurationManager.ConnectionStrings["SCB"].ToString());
            }

            ProductService.FetchData();
            //if ((DateTime.Now.Equals(ReloadDataTime) && !ProductService.IsLoading) ||
            //    ProductService.NeedLoadData)
            //{
            //    var thread = new Thread(ProductService.FetchData);
            //    thread.Start();
            //}
        }
    }

    public class CategoryService
    {
        private static IEnumerable<UICategoryModels> m_LeftPanelData;

        public static IEnumerable<UICategoryModels> LeftPanelData
        {
            get
            {
                if (m_LeftPanelData == null)
                {
                    m_LeftPanelData = GetSubcategoris(0);
                }
                return m_LeftPanelData;
            }
        }

        public static IEnumerable<UICategoryModels> GetSubcategoris(int id)
        {
            if (DataRespository.ProductService.Categories == null && DataRespository.ProductService.IsLoading)
            {
                return null;
            }
            return DataRespository.ProductService.Categories.
                Where(q => q.ParentId == id).Select(q => new UICategoryModels
                                                            {
                                                                Id = q.Id,
                                                                Name = q.Name,
                                                                Subcategories =
                                                                    (DataRespository.ProductService.Categories.Where(
                                                                        p => p.ParentId == q.Id).Select(
                                                                            p => new UICategoryModels
                                                                                     {
                                                                                         Id = p.Id,
                                                                                         Name = p.Name,
                                                                                         Subcategories = (DataRespository.ProductService.Categories.Where(
                                                                                             a => a.ParentId == p.Id)).Select(b => new UICategoryModels
                                                                                     {
                                                                                         Id = b.Id,
                                                                                         Name = b.Name
                                                                                     }).Take(5)
                                                                                     })).Take(10)
                                                            });
        }

        public static DTOCategory GetCategoryParentId(int id)
        {
            return DataRespository.ProductService.Categories.First(q => q.Id == id);
        }

        public static IEnumerable<DTOCategory> AllCategories
        {
            get
            {
                return DataRespository.ProductService.Categories;
            }
        }
    }

    public class ProductService
    {
        public static DTOProduct GetProduct(int id)
        {
            return DataRespository.ProductService.Products.First(q => q.Id == id);
        }

        public static IEnumerable<DTOProduct> AllProducts
        {
            get { return DataRespository.ProductService.Products; }
        }

        /// <summary>
        /// get all product with title contains [title] or has category title contains [title]
        /// </summary>
        /// <param name="title"></param>
        /// <returns></returns>
        public static List<DTOProduct> GetProductsByTitle(string title)
        {
            IEnumerable<DTOProduct> products = DataRespository.ProductService.Products;
            IEnumerable<int> categories = from c in DataRespository.ProductService.Categories where c.Name.Contains(title) select c.Id;

            return (from p in products where (p.Title.Contains(title) || categories.Contains(p.CategoryId)) select p).ToList();
        }

        /// <summary>
        /// get all product that has same category
        /// </summary>
        /// <param name="title"></param>
        /// <returns></returns>
        public static List<DTOProduct> GetProductsByCategoryId(int categoryId)
        {
            IEnumerable<DTOProduct> products = DataRespository.ProductService.Products;

            return (from p in products where (p.CategoryId == categoryId) select p).ToList();
        }

        /// <summary>
        /// get all product that has title = [productTitle]
        /// </summary>
        /// <param name="productTitle"></param>
        /// <returns></returns>
        public static List<DTOProduct> GetProductsByProductTitle(int productId, string productTitle)
        {
            IEnumerable<DTOProduct> products = DataRespository.ProductService.Products;

            return (from p in products where (p.Title == productTitle && p.Id != productId) orderby p.Price ascending select p).ToList();
        }
    }

    public class ProviderService
    {
        public static IEnumerable<DTOProvider> GetProviderAllLocations()
        {
            return DataRespository.ProductService.Providers.Select(p => GetProviderLocation(p.Id, p.Name));

        }

        public static DTOProvider GetProviderLocation(int providerId, string providerName)
        {
            var provider = DataRespository.ProductService.Providers.FirstOrDefault(q => q.Id == providerId);
            provider.ProviderLocations = DataRespository.ProductService.ProviderLocations.Where(q => q.ProviderId == providerId);
            return provider;
        }
    }

    public class SearchHistoryService
    {
        private static Dictionary<string, DTOSearchHistory> _searchHistories;

        private static void UpdateSearchHistories()
        {
            if (_searchHistories == null || _searchHistories.Count() < 0)
            {
                _searchHistories = new Dictionary<string, DTOSearchHistory>();
                List<DTOSearchHistory> searchHistories = DataRespository.ProductService.Searchhistories;
                if (searchHistories != null)
                {
                    foreach (DTOSearchHistory dtoSearchHistory in searchHistories)
                    {
                        if (_searchHistories.ContainsKey(dtoSearchHistory.Text))
                            _searchHistories[dtoSearchHistory.Text].Count += dtoSearchHistory.Count;
                        else
                            _searchHistories.Add(dtoSearchHistory.Text, dtoSearchHistory);
                    }
                }
            }
        }

        public static List<DTOSearchHistory> GetSearchHistories()
        {
            UpdateSearchHistories();

            return _searchHistories.Values.ToList<DTOSearchHistory>();
        }

        public static void UpdateSearchHistory(DTOSearchHistory dtoSearchHistory)
        {
            UpdateSearchHistories();
            DataRespository.ProductService.UpdateSearchHistory(dtoSearchHistory);

            if (_searchHistories.ContainsKey(dtoSearchHistory.Text))
                _searchHistories[dtoSearchHistory.Text].Count += dtoSearchHistory.Count;
            else
                _searchHistories.Add(dtoSearchHistory.Text, dtoSearchHistory);
        }
    }
}